<?php
require_once 'lib/controller.php';
require_once 'views/StandardView.php';
require_once 'models/EmailModel.php';
require_once 'lib/PxPay_OpenSSL.inc.php';
$standardView = new StandardView($html, $_GET, $db);
$email = new EmailModel();
$price = 499.00;

# DATABASE METHODS

/**
 * Check if a transaction has already been recorded
 *
 * @return bool
 * @param int $merchantReference
 */
function hasTransaction($merchantReference)
{
    global $db;
    $hasTransaction = FALSE;
    $sql = <<< EOT
        SELECT Success
        FROM DPSTransaction
        WHERE
            TxnType = 'AlertsPackage' AND
            Success=1 AND
            ID = %d
EOT;
    $sql = sprintf($sql, $merchantReference);
    $result = $db->query($sql);
    if ($db->rowCount($result) > 0) {
        $hasTransaction = TRUE;
    }
    return $hasTransaction;
}
/**
 * Add order information to the database
 *
 * @return int
 * @param string $txnType
 * @param mixed $amountInput
 * @param mixed $txnData1
 * @param mixed $txnData2
 * @param mixed $txnData3
 * @param mixed $currencyInput
 * @param mixed $emailAddress
 */
function addOrder($txnType, $amountInput, $txnData1, $txnData2, $txnData3, $currencyInput, $emailAddress)
{
    global $db;
    $txnType = $db->escape($txnType);
    $amountInput = $db->escape($amountInput);
    $txnData1 = $db->escape($txnData1);
    $txnData2 = $db->escape($txnData2);
    $txnData3 = $db->escape($txnData3);
    $currencyInput = $db->escape($currencyInput);
    $emailAddress = $db->escape($emailAddress);
    $sql = <<< EOT
        INSERT
            INTO DPSTransaction (TxnType, Success, AmountSettlement, TxnData1, TxnData2, TxnData3, CurrencyInput, EmailAddress)
            VALUES ('Alert', 0, '%s', '%s', '%s', '%s', '%s', '%s')

EOT;
    $sql = sprintf($sql,
        $amountInput,
        $txnData1,
        $txnData2,
        $txnData3,
        $currencyInput,
        $emailAddress
    );
    $result = $db->query($sql);
    $insertId = 0;
    if ($result === TRUE) {
        $insertId = $db->insertID();
    }
    return $insertId;
}
/**
 * Add alerts package to the database
 *
 * @return int
 * @param int $userId
 */
function addPackage($userId)
{
    global $db;
    $sql = <<< EOT
        INSERT
            INTO AlertsPackage (UserId, TransId, Enabled, Remaining)
            VALUES (%d, 0, 0, 0)

EOT;
    $sql = sprintf($sql, $userId);
    $result = $db->query($sql);
    $insertId = 0;
    if ($result === TRUE) {
        $insertId = $db->insertID();
    }
    return $insertId;
}
/**
 * Add alerts package to the database
 *
 * @return bool
 * @param int $packageId
 * @param int $remaining
 */
function setPackage($packageId, $remaining)
{
    global $db;
    $sql = <<< EOT
        UPDATE AlertsPackage
            SET
                Enabled = 1,
                Remaining = %d
        WHERE
            Id = %d

EOT;
    $sql = sprintf($sql,
        $remaining,
        $packageId
    );
    $success = $db->query($sql);
    return $success === TRUE;
}
/**
 * Update order information to the database
 *
 * @return bool
 * @param int $success
 * @param mixed $amountSettlement
 * @param int $authCode
 * @param mixed $cardName
 * @param mixed $cardNumber
 * @param mixed $dateExpiry
 * @param mixed $dpsBillingId
 * @param mixed $billingId
 * @param mixed $cardHolderName
 * @param mixed $dpsTxnRef
 * @param mixed $txnData1
 * @param mixed $txnData2
 * @param mixed $txnData3
 * @param mixed $currencySettlement
 * @param mixed $clientInfo
 * @param mixed $txnId
 * @param mixed $currencyInput
 * @param mixed $emailAddress
 * @param int $merchantReference
 * @param mixed $responseText
 * @param mixed $txnMac
 */
function updateOrder($merchantReference, $success, $amountSettlement, $authCode, $cardName, $cardNumber, $dateExpiry, $dpsBillingId, $billingId, $cardHolderName, $dpsTxnRef, $txnData1, $txnData2, $txnData3, $currencySettlement, $clientInfo, $txnId, $currencyInput, $emailAddress, $responseText, $txnMac)
{
    global $db;
    $sql = <<< EOT
        UPDATE DPSTransaction
            SET
                Success = %d,
                AmountSettlement = '%s',
                AuthCode = %d,
                CardName = '%s',
                CardNumber = '%s',
                DateExpiry = '%s',
                DpsBillingId = '%s',
                BillingId = '%s',
                CardHolderName = '%s',
                DpsTxnRef = '%s',
                TxnData1 = '%s',
                TxnData2 = '%s',
                TxnData3 = '%s',
                CurrencySettlement = '%s',
                ClientInfo = '%s',
                TxnId = '%s',
                CurrencyInput = '%s',
                EmailAddress = '%s',
                ResponseText = '%s',
                TxnMac = '%s'
        WHERE ID = %d
EOT;
    $sql = sprintf($sql,
        $success,
        $db->escape($amountSettlement),
        $authCode,
        $db->escape($cardName),
        $db->escape($cardNumber),
        $db->escape($dateExpiry),
        $db->escape($dpsBillingId),
        $db->escape($billingId),
        $db->escape($cardHolderName),
        $db->escape($dpsTxnRef),
        $db->escape($txnData1),
        $db->escape($txnData2),
        $db->escape($txnData3),
        $db->escape($currencySettlement),
        $db->escape($clientInfo),
        $db->escape($txnId),
        $db->escape($currencyInput),
        $db->escape($emailAddress),
        $db->escape($responseText),
        $db->escape($txnMac),
        $merchantReference
    );
   $result = $db->query($sql);
    return $result === TRUE;
}
/**
 * Retrieve the domain-specific values for connecting to pxpay
 *
 * @return array[string]string
 */
function getPxPayValues()
{
    global $db;
    $values = array(
        '' => ''
    );
    $sql = <<< EOT
        SELECT Name, Value
        FROM Local
        WHERE Name LIKE 'pxPay%'
EOT;
    $result = $db->query($sql);
    if ($db->rowCount($result) > 0) {
        while (TRUE) {
            $row = $db->fetch($result);
            if (empty($row)) {
                break;
            }
            $name = strval($row['Name']);
            $values[$name] = $db->unescape($row['Value']);
        }
    }
    return $values;
}
/**
 * Get a users email address
 *
 * @return string
 * @param int $userId
 */
function getEmail($userId)
{
    global $db;
    $email = '';
    $sql = <<< EOT
        SELECT Email
        FROM Users
        WHERE
            Id = %d
EOT;
    $sql = sprintf($sql, $userId);
    $result = $db->query($sql);
    if ($db->rowCount($result) > 0) {
        $row = $db->fetch($result);
        $email = $db->unescape($row['Email']);
    }
    return $email;
}
/**
 * Add alerts package to the database
 *
 * @return int
 * @param int $packageId
 * @param int $transId
 */
function setPackageReference($packageId, $transId)
{
    global $db;
    $sql = <<< EOT
        UPDATE AlertsPackage
            SET TransId = %d
        WHERE
            Id = %d

EOT;
    $sql = sprintf($sql,
        $packageId,
        $transId
    );
    $result = $db->query($sql);
    $insertId = 0;
    if ($result === TRUE) {
        $insertId = $db->insertID();
    }
    return $insertId;
}
# VIEW METHODS

/** Show an important notice
 *
 * @return string
 * @param string $content
 */
function importantNotice($content)
{
    return <<< EOT
        <div class="important">
            <h2>Important Notice</h2>
            $content
        </div>
        
EOT;
}
/** The package order receipt
 *
 * @return string
 * @param int $merchantReference
 * @param string $amountSettlement
 * @param string $currencyInput
 * @param string $customerEmail
 * @param string $clientInfo
 * @param string $people
 * @param string $expiryDate
 * @param string $cardName
 * @param string $cardHolderName
 *
 */
function viewReceipt($merchantReference, $amountSettlement, $currencyInput, $customerEmail, $clientInfo, $expiryDate, $cardName, $cardHolderName)
{
    return <<< EOT
    <h2>Corporate Package for Email Alerts Receipt</h2>
    <p>Order #: $merchantReference</p>
    <p>GST: 95-288-030</p>
    <p>Sum of: $$amountSettlement $currencyInput</p>
    <p>From: $customerEmail - IP address: $clientInfo</p>
    <p>For: Corporate Package for Email Alerts for 1000 people
    <p>Expires: $expiryDate</p>
    <p>Card Type: $cardName</p>
    <p>Card Name: $cardHolderName</p>

EOT;
}

# MODEL METHODS

/**
 * Send an email
 *
 * @return bool
 * @param string $fromName
 * @param string $fromEmail
 * @param string $toName
 * @param string $toEmail
 * @param string $subject
 * @param string $message
 */
function sendEmail($fromName, $fromEmail, $toName, $toEmail, $subject, $message)
{
    global $email;
    $email->setFromName($fromName);
    $email->setFromEmail($fromEmail);
    $email->setToName($toName);
    $email->setToEmail($toEmail);
    $email->setSubject($subject);
    $email->setMessage($message);
    return $email->send();
}
/**
 * Send an email to the customer
 *
 * @return bool
 * @param string $toEmail
 * @param string $subject
 * @param string $message
 */
function sendCustomerEmail($toEmail, $subject, $message) {
    $fromName = 'A Memory Tree';
    $fromEmail = 'order@amemorytree.co.nz';
    $toName = $toEmail;
    $message = '<p>Thank you for your order.</p>'.$message;
    return sendEmail($fromName, $fromEmail, $toName, $toEmail, $subject, $message);
}
/**
 * Send an email to our business
 *
 * @return bool
 * @param string $subject
 * @param string $message
 */
function sendBusinessEmail($subject, $message) {
    $fromName = 'A Memory Tree';
    $fromEmail = 'order@amemorytree.co.nz';
    $toName = $fromName;
    $toEmail = $fromEmail;
    $message = '<p>An Alerts Package order has been received.</p>'.$message;
    return sendEmail($fromName, $fromEmail, $toName, $toEmail, $subject, $message);
}
/**
 * Show the result of the order
 *
 * @return string
 * @param PxPay_OpenSSL &$pxpay
 */
function print_result(&$pxpay)
{
    global $helper;
    $enc_hex = strval($_REQUEST["result"]);
    #getResponse method in PxPay object returns PxPayResponse object
    #which encapsulates all the response data
    /*.PxPayResponse.*/ $rsp  = @$pxpay->getResponse($enc_hex);
    $merchantReference  = intval($rsp->getMerchantReference());
    $success            = intval($rsp->getSuccess());   # =1 when request succeeds
    $amountSettlement   = strval($rsp->getAmountSettlement());
    $authCode           = intval($rsp->getAuthCode());  # from bank
    $cardName           = strval($rsp->getCardName());  # e.g. "Visa"
    $cardNumber         = strval($rsp->getCardNumber()); # Truncated card number
    $cardExpiryDate     = strval($rsp->getDateExpiry()); # in mmyy format
    $dpsBillingId       = strval($rsp->getDpsBillingId());
    $billingId          = strval($rsp->getBillingId());
    $cardHolderName     = strval($rsp->getCardHolderName());
    $dpsTxnRef          = strval($rsp->getDpsTxnRef());
    $txnData1           = intval($rsp->getTxnData1());
    $txnData2           = strval($rsp->getTxnData2());
    $txnData3           = strval($rsp->getTxnData3());
    $currencySettlement = strval($rsp->getCurrencySettlement());
    $clientInfo         = strval($rsp->getClientInfo()); # The IP address of the user who submitted the transaction
    $txnId              = strval($rsp->getTxnId());
    $currencyInput      = strval($rsp->getCurrencyInput());
    $emailAddress       = strval($rsp->getEmailAddress());
    $responseText       = strval($rsp->getResponseText());
    $txnMac             = strval($rsp->getTxnMac()); # An indication as to the uniqueness of a card used in relation to others

    $packageId = intval($txnData2);
    $customerEmail = $txnData3;

    $alertsPage = '<a href="alerts.php">Alerts page</a>';
    $expiryDate = date('d M Y', $helper->changeTime(strtotime('now'), 1));
    
    $style = <<< EOT
    <style type="text/css">
    #contentarea #centerbar div.important { border: 1px solid #C12A0B; margin: 1em 0; }
    #contentarea #centerbar div.important h2 { background: #B80101; color: white; margin-top: 0; padding: 0.5em; }
    #contentarea #centerbar div.important p { margin: 0.5em; }
    .heading { color: #C12A0B; font-weight: bold; }
    </style>

EOT;
    $successMessage = <<< EOT
    <h2>Purchase Successful</h2>
    <p>Thank you. Your receipt has been emailed to you (there is a copy below).</p>
    <p>Back to the $alertsPage.</p>

EOT;
    $unsuccessfulMessage = <<< EOT
    <h2>Purchase Unsuccessful</h2>
    <p class="error">Please try again.</p>
	<p>Back to the $alertsPage.</p>
EOT;

    if ($rsp->getSuccess() === "1") {
        $spamNotice = 'Spam filters on your email can sometimes wrongly detect A Memory Tree emails as spam. If you do not receive your receipt by email within 24 hours, please check you Junk Mail, Spam, or Bulk folders.  Also please contact your mail administrator to discuss how to prevent A Memory Tree emailed being incorrectly classified as spam.';
        $issuesNotice = 'If you have any issues or questions, please contact us at <a href="mailto:order@amemorytree.co.nz">order@amemorytree.co.nz</a>';
        $receiptNotice = 'A receipt was automatically emailed to you when your payment was accepted. Details of your purchase including GST component is in that email.';
        $pageSpamNotice = '<p><span class="heading">SPAM</span> - '.$spamNotice.'</p>';
        $pageIssuesNotice = '<p><span class="heading">NOTICE</span> - '.$issuesNotice.'</p>';
        $emailIssuesNotice = '<p>'.$issuesNotice.'</p>';
        $pageReceiptNotice = '<p><span class="heading">RECEIPT</span> - '.$receiptNotice.'</p>';
        $pageNotice = importantNotice($pageSpamNotice.$pageIssuesNotice.$pageReceiptNotice);
        $emailNotice = $emailIssuesNotice;
        $receipt = viewReceipt($merchantReference, $amountSettlement, $currencyInput, $customerEmail, $clientInfo, $expiryDate, $cardName, $cardHolderName);
        if (!hasTransaction($merchantReference)) {
            updateOrder($merchantReference, $success, $amountSettlement, $authCode, $cardName, $cardNumber, $cardExpiryDate, $dpsBillingId, $billingId, $cardHolderName, $dpsTxnRef, $txnData1, $txnData2, $txnData3, $currencySettlement, $clientInfo, $txnId, $currencyInput, $emailAddress, $responseText, $txnMac);
            setPackage($packageId, 1000);
            $customerSubject = 'Corporate Package for Email Alerts at www.amemorytree.co.nz';
            $businessSubject = 'Corporate Package for Email Alerts from ' . $customerEmail;
            $customerMessage = $emailNotice.$receipt;
            $businessMessage = $receipt;
            sendCustomerEmail($customerEmail, $customerSubject, $customerMessage);
            sendBusinessEmail($businessSubject, $businessMessage);
        }
        $text = $style.$successMessage.$pageNotice.$receipt;
    } else {
        $text = $unsuccessfulMessage;
    }
    return '<div id="centerbar">'.$text.'</div>';
}
/**
 * Redirect to the payment website
 *
 * @return void
 * @param PxPay_OpenSSL $pxpay
 */
function redirect_form($pxpay)
{
    global $helper;
    global $price;
    $userId = intval($helper->get('userid'));
    $total = $price;
    $packageId = addPackage($userId);
    $email = getEmail($userId);
    $errors = '';
    if (empty($userId)) {
        $errors .= '&useriderror=yes';
    }
    if (empty($email)) {
        $errors .= '&emailerror=yes';
    }
    if (!empty($errors)) {
        $host = $_SERVER['HTTP_HOST'];
        $path = '/alerts.php';
        $query = $_SERVER['QUERY_STRING'];
        header("Location: HTTP://$host$path?$query$errors");
    } else {
        $amountInput = $total;
        $txnType = 'AlertsPackage';
        $txnData1 = strval($userId);
        $txnData2 = strval($packageId);
        $txnData3 = $email;
        $currencyInput = 'NZD';
        $emailAddress = 'theteam@amemorytree.co.nz';
        $merchantReference = addOrder($txnType, $amountInput, $txnData1, $txnData2, $txnData3, $currencyInput, $emailAddress);
        setPackageReference($packageId, $merchantReference);
        $txnId = uniqid("ID");
        $http_host   = getenv("HTTP_HOST");
        $request_uri = getenv("SCRIPT_NAME");
        $server_url  = "http://$http_host";
        $script_url = (version_compare(PHP_VERSION, "4.3.4", ">=") === TRUE) ?"$server_url$request_uri" : "$server_url/$request_uri";

        $request = new PxPayRequest();
        $request->setTxnType('Purchase');
        $request->setMerchantReference(strval($merchantReference));
        $request->setAmountInput($amountInput);
        $request->setTxnData1($txnData1);
        $request->setTxnData2($txnData2);
        $request->setTxnData3($txnData3);
        $request->setCurrencyInput($currencyInput);
        $request->setEmailAddress($emailAddress);
        $request->setUrlFail($script_url);			# can be a dedicated failure page
        $request->setUrlSuccess($script_url);			# can be a dedicated success page
        $request->setTxnId($txnId);  

        #The following properties are not used in this case
        # $request->setEnableAddBillCard($EnableAddBillCard);    
        # $request->setBillingId($BillingId);
        # $request->setOpt($Opt);


        // obtain input XML
        $request_string = @$pxpay->makeRequest($request);
        //Obtain output XML
        $response = new MifMessage($request_string);

        // Parse output XML
        $url = $response->get_element_text("URI");
        //$valid = $response->get_attribute("valid");

        // Redirect to payment page
        header("Location: ".$url);
    }
}
$pxPayValues = getPxPayValues();
$pxPayUrl = $pxPayValues['pxPayUrl'];
$pxPayUserId = $pxPayValues['pxPayUserId'];
$pxPayKey = $pxPayValues['pxPayKey'];
$pxpay = new PxPay_OpenSSL($pxPayUrl, $pxPayUserId, $pxPayKey);
if (isset($_REQUEST["result"])) {
    $content = print_result($pxpay);
    echo $standardView->render($content);
} else if (isset($_REQUEST["userid"])) {
    redirect_form($pxpay);
}
?>
